package com.zzr.zzrbackend.service.Impl;


import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zzr.zzrbackend.config.JwtInterceptor;
import com.zzr.zzrbackend.mapper.AuthenticationCodeMapper;
import com.zzr.zzrbackend.mapper.RelationMapper;
import com.zzr.zzrbackend.mapper.UserInfoMapper;
import com.zzr.zzrbackend.mapper.UserMapper;
import com.zzr.zzrbackend.pojo.domain.Relation;
import com.zzr.zzrbackend.pojo.domain.User;
import com.zzr.zzrbackend.pojo.domain.UserInfo;
import com.zzr.zzrbackend.pojo.dto.CommonResult;
import com.zzr.zzrbackend.pojo.dto.param.*;
import com.zzr.zzrbackend.pojo.dto.result.*;
import com.zzr.zzrbackend.service.LoginService;
import com.zzr.zzrbackend.util.AesEncryptUtils;
import com.zzr.zzrbackend.util.GetRandomString;
import com.zzr.zzrbackend.util.MD5Utils;
import com.zzr.zzrbackend.util.TokenUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.NoSuchAlgorithmException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class LoginServiceImpl implements LoginService {
    @Resource
    UserMapper userMapper;
    @Resource
    AuthenticationCodeMapper authenticationCodeMapper;
    @Resource
    UserInfoMapper userInfoMapper;
    @Resource
    private JwtInterceptor jwtInterceptor;
    @Resource
    HttpServletRequest request;
    @Resource
    RelationMapper relationMapper;

    @Override
    public CommonResult<LoginResult> login(LoginParam loginParam, HttpServletRequest request,
                                           HttpServletResponse response) throws NoSuchAlgorithmException {
        String userName = loginParam.getUserName();

        //对账号密码进行查询，密码进行MD5加密
        loginParam.setPassword(MD5Utils.getMD5Str(loginParam.getPassword()));

        User user = userMapper.selectByUserNameAndPassword(loginParam);
        Integer userId = userMapper.selectIdByUserName(userName);

        LoginResult loginResult = new LoginResult();

        if (user == null) {
            return CommonResult.userPasswordWrong();
        }
        //设置token
        if (userId != null) {
            Map<String, Object> claims = new HashMap<>();
            claims.put("id", userId);
            claims.put("userName", userName);
            claims.put("permission", user.getPermission());
            String token = TokenUtils.generateJwtToken(claims);
            loginResult.setToken(token);
        } else {
            return CommonResult.fail_login();
        }

        UserInfo userInfo = userInfoMapper.selectByPrimaryKey(userId);

        //返回登录的封装类
        loginResult.setId(userId);
        loginResult.setPermission(user.getPermission());
        loginResult.setUserName(user.getUsername());
        loginResult.setIsSetIdentity(user.getIsSetIdentity());
        loginResult.setIsCertification(user.getIsCertification());
        loginResult.setHeadPicUrl(userInfo.getHeadPicUrl());

        //判断是否绑定家长
        try {
            if (user.getPermission() == 1) {
                Relation relation = relationMapper.selectByChild(userId);
                if (relation == null) {
                    loginResult.setIsBindParents(0);
                } else {
                    loginResult.setIsBindParents(relation.getParentId());
                }
            } else {
                loginResult.setIsBindParents(-1);
            }
        } catch (Exception e) {
            loginResult.setIsBindParents(0);
        }

        return CommonResult.success(loginResult);
    }

    @Override
    public CommonResult<LoginResult> loginNew(String param) throws Exception {

        String decrypt;

        try {
            decrypt = AesEncryptUtils.decrypt(param, AesEncryptUtils.KEY);
        } catch (Exception e) {
            e.printStackTrace();
            return CommonResult.fail();
        }

        System.out.println("解密后：" + decrypt);

        JSONObject jsonObject1 = JSONObject.parseObject(decrypt);
        ObjectMapper objectMapper = new ObjectMapper();
        LoginParam loginParam = objectMapper.convertValue(jsonObject1, LoginParam.class);
        System.out.println("1");

        String userName = loginParam.getUserName();

        //对账号密码进行查询，密码进行MD5加密
        loginParam.setPassword(MD5Utils.getMD5Str(loginParam.getPassword()));

        User user = userMapper.selectByUserNameAndPassword(loginParam);
        Integer userId = userMapper.selectIdByUserName(userName);

        LoginResult loginResult = new LoginResult();

        if (user == null) {
            return CommonResult.userPasswordWrong();
        }
        //设置token
        if (userId != null) {
            Map<String, Object> claims = new HashMap<>();
            claims.put("id", userId);
            claims.put("userName", userName);
            claims.put("permission", user.getPermission());
            String token = TokenUtils.generateJwtToken(claims);
            loginResult.setToken(token);
        } else {
            return CommonResult.fail_login();
        }

        UserInfo userInfo = userInfoMapper.selectByPrimaryKey(userId);

        //返回登录的封装类
        loginResult.setId(userId);
        loginResult.setPermission(user.getPermission());
        loginResult.setUserName(user.getUsername());
        loginResult.setIsSetIdentity(user.getIsSetIdentity());
        loginResult.setIsCertification(user.getIsCertification());
        loginResult.setHeadPicUrl(userInfo.getHeadPicUrl());

        //判断是否绑定家长
        try {
            if (user.getPermission() == 1) {
                Relation relation = relationMapper.selectByChild(userId);
                if (relation == null) {
                    loginResult.setIsBindParents(0);
                } else {
                    loginResult.setIsBindParents(relation.getParentId());
                }
            } else {
                loginResult.setIsBindParents(-1);
            }
        } catch (Exception e) {
            loginResult.setIsBindParents(0);
        }


        return CommonResult.success(loginResult);
    }

    @Override
    @Transactional
    public CommonResult<NoData> register(RegisterParam registerParam) throws NoSuchAlgorithmException {

        User user = new User();

        //设置user基本信息
        user.setUsername(registerParam.getUserName());
        user.setPhone(registerParam.getPhone());
        user.setIsCertification(0);
        user.setIsSetIdentity(0);
        //验证前后2次密码是否一致
        if (!registerParam.getPassword().equals(registerParam.getConfirmPassword())) {
            return CommonResult.userPasswordWrong();
        }

        //将加密的password存入user表
        user.setPassword(MD5Utils.getMD5Str(registerParam.getPassword()));

        //通过手机短信验证
        Integer code = authenticationCodeMapper.getCodeByPhone(user.getPhone());

        if (!registerParam.getCode().equals(code)) {
            return CommonResult.fail("验证码错误");
        }

        //获取当前时间戳
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());

        Long endTime = timestamp.getTime() / 1000;
        Long startTime = authenticationCodeMapper.getCodeTime(user.getPhone());

        long time = (endTime - startTime) / 60;

        if (time > 5 || endTime < startTime) {
            return CommonResult.fail("验证码已过期");
        }

        //检验user表中是否已存在相同userName的账户
        User user2 = userMapper.selectByUserName(user.getUsername());

        if (user2 != null) {
            return CommonResult.userUsernameExist();
        }

        //检验user表中是否已存在相同手机号的账户
        List<User> user3 = userMapper.selectByPhone(registerParam.getPhone());

        if (user3.size() != 0) {
            return CommonResult.fail("手机号已注册");
        }

        //插入user表
        userMapper.insert(user);

        //初始化userinfo表
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(user.getId());
        userInfo.setUserName(user.getUsername());
        userInfoMapper.insertInit(userInfo);

        return CommonResult.success();
    }

    @Override
    public CommonResult<SetIdentityResult> setIdentity(SetIdentityParam setIdentityParam) {

        Integer userId = jwtInterceptor.getUserId(request);

        User user = userMapper.selectById(userId);

        if (user == null) {
            return CommonResult.fail("数据库异常，查无此人");
        }

        if (user.getIsSetIdentity() != 0) {
            return CommonResult.fail("用户已经设置过身份");
        }

        Integer j = userMapper.updateByIdentity(user.getIsSetIdentity(), userId);
        if (j == 0) {
            return CommonResult.success("更新登录状态失败");
        }

        //获取权限对应的数字i
        Integer i = setIdentityParam.getPermission();

        if (i == 0 || i == 1 || i == 2 || i == 3) {
            Integer k = userMapper.updatePermissionByUserId(i, userId);
            if (k == 0) {
                return CommonResult.fail("数据库异常，权限插入失败");
            }
        }
        User user2 = userMapper.selectById(userId);
        if (user2 == null) {
            return CommonResult.fail("数据库异常，查无此人");
        }

        SetIdentityResult setIdentityResult = new SetIdentityResult();
        setIdentityResult.setPermission(user2.getPermission());

        //重新给予token
        user = userMapper.selectById(userId);
        if (userId != null) {
            Map<String, Object> claims = new HashMap<>();
            claims.put("id", userId);
            claims.put("userName", user.getUsername());
            claims.put("permission", user.getPermission());
            String token = TokenUtils.generateJwtToken(claims);
            setIdentityResult.setToken(token);
        } else {
            return CommonResult.fail_login();
        }

        return CommonResult.success(setIdentityResult);
    }

    @Override
    public CommonResult<NoData> setChildInformation(ChildInformationParam childInformationParam) {

        Integer userId = jwtInterceptor.getUserId(request);
        User user = userMapper.selectById(userId);

        if (user.getPermission() != 1) {
            return CommonResult.fail("权限验证失败，不是小孩身份");
        }

        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(userId);
        userInfo.setUserName(user.getUsername());
        userInfo.setGender(childInformationParam.getGender());
        userInfo.setNativePlace(childInformationParam.getNativePlace());
        userInfo.setAge(childInformationParam.getAge());
        userInfo.setGrade(childInformationParam.getGrade());
        userInfo.setSign(childInformationParam.getSign());
        userInfo.setHeadPicUrl(childInformationParam.getHeadPicUrl());

        UserInfo userInfo1 = userInfoMapper.selectByPrimaryKey(userInfo.getUserId());

        if (userInfo1 == null) {
            //将信息插入到userInfo表
            userInfoMapper.insertSelective(userInfo);

        }
        //将信息更新到userInfo表
        userInfoMapper.updateChild(userInfo);

        Integer j = userMapper.updateByCertification(userId);
        if (j == 0) {
            return CommonResult.success("更新状态失败");
        }

        return CommonResult.success();
    }

    @Override
    public CommonResult<NoData> setParentInformation(ParentInformationParam parentInformationParam) {

        Integer userId = jwtInterceptor.getUserId(request);
        User user = userMapper.selectById(userId);

        if (user.getPermission() != 2) {
            return CommonResult.fail("权限验证失败，不是父母身份");
        }

        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(userId);
        userInfo.setUserName(user.getUsername());
        userInfo.setGender(parentInformationParam.getGender());
        userInfo.setNativePlace(parentInformationParam.getNativePlace());
        userInfo.setAge(parentInformationParam.getAge());
        userInfo.setRelation(parentInformationParam.getRelation());
        userInfo.setHomeSituation(parentInformationParam.getHomeSituation());
        userInfo.setSoftwareSituation(parentInformationParam.getSoftwareSituation());
        userInfo.setRemarkChild(parentInformationParam.getRemarkChild());
        userInfo.setRemarkVolunteer(parentInformationParam.getRemarkVolunteer());
        userInfo.setHeadPicUrl(parentInformationParam.getHeadPicUrl());
        userInfo.setWorkAddress(parentInformationParam.getWorkAddress());

        UserInfo userInfo1 = userInfoMapper.selectByPrimaryKey(userInfo.getUserId());

        if (userInfo1 == null) {
            //将信息插入到userInfo表
            userInfoMapper.insertSelective(userInfo);

        }
        //将信息更新到userInfo表
        userInfoMapper.updateParent(userInfo);

        Integer j = userMapper.updateByCertification(user.getId());
        if (j == 0) {
            return CommonResult.success("更新状态失败");
        }


        return CommonResult.success();
    }

    @Override
    public CommonResult<GetInvitationCodeResult> getInvitationCode() {

        Integer userId = jwtInterceptor.getUserId(request);
        User user = userMapper.selectById(userId);
        if (user == null) {
            return CommonResult.fail("用户不存在，数据库异常");
        }
        if (user.getPermission() != 2) {
            return CommonResult.fail("权限异常，不是父母权限");
        }
        //获取生成邀请码
        String code = GetRandomString.getRandomString3(8);
        GetInvitationCodeResult getInvitationCodeResult = new GetInvitationCodeResult();

        List<Relation> relation = relationMapper.select(userId);
        if (relation.size() == 0) {
            int i = relationMapper.insert(userId, code);
            if (i == 0) {
                return CommonResult.fail("数据库插入失败");
            }
            getInvitationCodeResult.setCode(code);
            return CommonResult.success(getInvitationCodeResult);
        } else {
            List<Integer> childIdList = relationMapper.selectChildIdByParentId(userId);
            for (Integer id:childIdList){
                if(id == null){
                    relationMapper.updateNullCode(userId,code);
                    getInvitationCodeResult.setCode(code);
                    return CommonResult.success(getInvitationCodeResult);
                }
            }
            relationMapper.insert(userId, code);
            getInvitationCodeResult.setCode(code);
            return CommonResult.success(getInvitationCodeResult);
        }
    }

    @Override
    public CommonResult<NoData> setInvitationCode(InvitationCode invitationCode) {

        Integer childId = jwtInterceptor.getUserId(request);
        User user = userMapper.selectById(childId);
        if (user == null) {
            return CommonResult.fail("用户不存在，数据库异常");
        }
        if (user.getPermission() != 1) {
            return CommonResult.fail("权限异常，不是儿童权限");
        }

        Relation relation = relationMapper.selectByCode(invitationCode.getCode());

        if (relation == null) {
            return CommonResult.fail("邀请码错误");
        }

        Relation relation1 = relationMapper.selectByChild(childId);
        if(relation1 != null){
            //删除之前的账号
            relationMapper.deleteId(childId,relation1.getParentId());
            //绑定最新的父母账号
            relationMapper.updateChildId(childId, invitationCode.getCode(), relation.getParentId());
        }

        int i = relationMapper.updateChildId(childId, invitationCode.getCode(), relation.getParentId());

        if (i == 0) {
            return CommonResult.fail("绑定账号失败");
        }

        return CommonResult.success();
    }

    @Override
    public CommonResult<VerifyInvitationCodeResult> verifyInvitationCode() {

        Integer childId = jwtInterceptor.getUserId(request);
        User user = userMapper.selectById(childId);
        if (user.getPermission() != 1) {
            return CommonResult.fail("权限异常，不是儿童权限");
        }

        Relation relation = relationMapper.selectByChild(childId);
        if (relation == null) {
            return CommonResult.fail("数据库异常");
        }

        VerifyInvitationCodeResult verifyInvitationCodeResult = new VerifyInvitationCodeResult();
        verifyInvitationCodeResult.setIsCertification(relation.getIsCertification());

        return CommonResult.success(verifyInvitationCodeResult);
    }

    @Override
    public CommonResult<NoData> verifyPhone(SeedCodeParam seedCodeParam) {

        //检验user表中是否已存在相同手机号的账户
        List<User> userList = userMapper.selectByPhone(seedCodeParam.getPhone());

        if (userList.size() != 0) {
            return CommonResult.fail("手机号已注册");
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult<NoData> findPassword(FindPasswordParam findPasswordParam) throws NoSuchAlgorithmException {
        //通过手机短信验证
        Integer code = authenticationCodeMapper.getCodeByPhone(findPasswordParam.getPhone());
        if (!findPasswordParam.getCode().equals(code)) {
            return CommonResult.fail("验证码错误");
        }

        String MD5Password = MD5Utils.getMD5Str(findPasswordParam.getPassword());

        Integer i = userMapper.updatePassword(findPasswordParam.getUserName(), MD5Password);
        if (i == 0) {
            return CommonResult.fail("数据更新失败");
        }
        return CommonResult.success();
    }

}
